You can use terrain as a passable and invisible entity for water, and use another model, block, or asset to represent the visible water.
just use the passable_ent pointer with c_trace. If the trace origin or end is inside the passable terrain, the passable_ent pointer is set to the terrain. You could set one of the skills of the terrain, and have your script check this skill to detect is as water.
(though I wish there was a way to detect when a player is inside a solid mesh / block for detecting if it accidentally became embedded in a solid after movement...)