FWIW I resolved this problem with two Z motors run from a single driver by adding a mechanical homing stage into my start up code. I added lower hard stop points to each side of the bed, one with each Z motor, and then run the bed down into those stops (at a low current) until the motors misstep. This sets a repeatable level between the two. Very simple and, so far, very reliable. The whole process goes like this:
1. Run Z axis up to its normal zero micro switch stop so we know roughly where we are.
2. Run Z axis all the way down at high speed to 10 mm above hard bottom stops
3. Reduce current and speed and run Z axis down a further 20 mm. This ensures that both motors will hit their end stops and misstep. The slow speed and low current keeps this process painless.
4. Run Z axis back up and run zero routine as usual. (In my case using a DC42 IR sensor)
(This assumes that the two motors are within 10 mm to start with. You can increase the 20 mm misstepping run if you think the error could be more than that.)
With the speed and current low, the maximum delta between the two motors should now be no more than one full step of the motor. This adds maybe 20 seconds to the start up Gcode but solves a lot of problems! Coupled with mesh leveling it's meant I never have to worry about bed flatness.
For hard stops I just printed sleeves that fit around the lead screws that limit downwards travel and transfer the load. Probably better would be hard stops on the frame, but I haven't found that to be necessary in practice.