In the first loop you clear the velocity change when you first encounter a sprite, but it may have already been in a collision by that point.
For example if the first rectangle hits the second, the second will receive a velocity change, which will be cleared before it is applied.
You may also need to run through the whole list multiple times to resolve all intersections.
Good god, I feel ridiculously foolish for missing that. I'll test that out later today and see if it fixes it, but it would explain a lot. Sometimes its the simple things I guess.
I had tried running through the process multiple times and that lessened the problem. Is this an actual approach that some physics engines take? It seems so inefficient.

Find content
Not Telling