Common, easy but ultimately wrong answer
Iterate along the vector in very small increments. Eventually they'll de-penetrate at a "reasonable" position, assuming you continue any additional constraints at each iteration. It's brute force, and for something simple, it's good enough. You will almost certainly need to add artificial max/min force limiters to your collision handler if you take this approach. If you don't like limiters, a high dampener, drag or friction value will hide any numerical issues. If you're making a phone game or doing a weekend jam, this will do the trick. See: Better Answer.
Wind back time using the last known position and your SAT penetration vector to find the correct time delta between frames of the collision. Don't artificially de-penetrate, re-calculate the physics from the time step at which the collision occurred.
When you de-penetrate then process collisions, you're effectively violating conservation of energy. You've taken an inelastic collision and turned it into an simple elastic collision without doing anything with the forces involved. You've either not absorbed them in the inelastic "crunch" that should have happened or if you're using a fixed coefficient of restitution you may over-compensate. Many physics engines don't handle that well. Depending on what kind of iterator you're using in your physics engine, you can run into numerical problems as well. Verlet iterators are pretty tolerant to that kind of thing because they're inherently positional, but others are not. If the extra error from force-moving objects accumulates your physics can become unstable over time.