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.