I2C flakiness: best strategy to identify and fix?

You have done most things right. A few things got my attention.

The I2C Slave is most sensitive for turning off the interrupts. Therefor the DHT or OneWire or NeoPixels libraries might cause problems.
Turning interrupts off for a very short time to copy the volatile variables is no problem.
You can try without turning the interrupts off as most others do. Suppose the 'gotData' is checked fast enough in the loop(), and if that is before a call to requestEvent() or receiveEvent() which could change the variables in the struct, then it is okay.

With the total length of the wires for SDA and SCL I mean to add every piece of wire. A star shaped bus of 20" each to four devices makes 80".

The pullup resistors for SDA and SCL should be according to the I2C specifications, and that is maximum 3 mA pull down current.
Internal pullup resistors: use it only for testing.
10k pullup resistors: when a sensor is directly next to the Arduino board.
4k7 is a normal value.
The longer the wires the lower the pullup resistors should be.
You have to calculate the total value of all the pullup resistors on every Arduino board and every module.
Suppose two Leonardo boards with 50k internal each and two modules with 10k each. The total pullup resistor will be 1 / (1/50k + 1/50k + 1/10k + 1/10k) = 4k1. That makes a pull-down current of 1.2 mA.
Then you could add pullup resistors of 4k7 to 5V to create a pull-down current of 2.2 mA.

You can test the pull-down current of a I2C bus. Turn everything on, call Wire.begin(), but keep the I2C bus idle. Then with a multimeter measure the current (shortcut current) of SDA to GND and of SCL to GND.

When something on the I2C bus has no power, then the SDA and SCL are pulled low, and the bus does not work. When you connect the 5V pin of one Leonardo to the 5V pin of the other Leonardo board, the voltage regulator gets a reverse current. It should work in most cases but it can be dangerous.

Suppose you have a very strong 5V 10A power supply. If that is added to the 5V pin, the voltage regulator might blow, because of the large reverse peak. It has happened to some.
Suppose you have two Arduino boards connected to two computers. If the 5V pins are connected and one computer is turned off, then current would flow into the computer that is turned off. Not every computer does like that.

One power supply is the safest. That is one power supply of 5V, with the output split to two wires, going to the USB connectors of the Arduino boards. With the GNDs of the Arduino boards still connected with a wire of course.
Or a 7.5V power supply going to the barrel jack power input of both boards.

What about some kind of waiting loop to wait for the SDA and SCL to go HIGH ? With a message on the display or a blinking led. For example waiting for 30 seconds.

Always checking the 'howMany' parameter in the receiveEvent() is a good idea.
At the begin of the receiveEvent(), the 'howMany' is the same as Wire.available().

Don't use Serial functions in the receiveEvent() or requestEvent(). I don't care what you do with an error, but don't use them.
The receiveEvent() and requestEvent() are real interrupt routines. The Serial functions use interrupts themself. That can cause a lot of troubles. I know that it is in the official Arduino examples, but that is terrible. Those interrupt routines should be very short to keep the I2C communication fast and reliable.
Remove those Serial.print and Serial.println from those functions right now.

Fritzing does not produce "real" schematics. When you learn KiCad or Eagle, you already know 50% of the other one. It takes time to learn to use them. Well... not only time, also frustration and asking yourself why those programs make it hard instead of easy.

I have had no problems with the pins of shield into an Arduino board. Not even with bad quality shields. But others have, after a few years.