[edit] There is a proper solution which I'll add as a separate answer, but since this technique is different enough to have its own uses (like if you want different grass models at the edges) I'll leave it here.

<strike>After digging around for a while, it looks like this is not possible. The closest I got was an OSL script using traceset to find the value, but it turns out that Blender OSL doesn't implement traceset.</strike>


I did come up with a workaround that more or less does what I want:

 1. Create an additional vertex group (I called it `water.edge`) on the emitter and assign all vertices to it.
 2. Add a Vertex Weight Mix modifier to the emitter, which copies the original `water` vertex group to `water.edge`.
 3. Below that add a Vertex Weight Edit modifier that edits `water.edge` and applies a custom falloff curve that starts at 0, rises to 1 then falls back to 0. This makes `water.edge` have its highest values where the `water` values are intermediate.
 4. Create a new particle system `yellow grass`, and use separate yellow grass variant particles.
 5. Use the `water.edge` vertex group to control the density and length of the `yellow grass` particle system.

Downside is the texture doesn't "blend" from one region to another, but at least I can get dry grass where I want it.


[![Here's a picture of that part of the modifier stack.][1]][1]


  [1]: https://i.sstatic.net/ROzoK.png