*First, I recommend using a free, open-source physics library like [Box2D][1] and just focusing on the aspects of your game that make it unique! If you insist on re-inventing the wheel, read on... note all physics engines are approximations, and while the method I outline below will be more accurate than your current model, Box2D's results will be far more realistic.*

<hr>
## For a quick way to model more accurate collision resolution of two objects A and B:
1. **Find the positions right before the collision.** I think you are already doing this by: "finding the shortest penetration vector and adding it to the AABB's position."
2. **Find the velocities right after the collision** using [Newtonian physics][3]:
    - For the case where mass is hard-coded as 1, simply swap the velocities (note static objects must have infinite mass):
      - A.v = B.u
      - B.v = A.u
    - If objects A and B have different masses:
      - A.v = (A.u * (A.m - B.m) + (2 * B.m * B.u)) / (A.m + B.m)
      - B.v = (B.u * (B.m - A.m) + (2 * A.m * A.u)) / (A.m + B.m)
   - where:
        - v: velocity after collision
        - u: velocity before collision
        - m: mass (use the largest number possible for the mass of a fixed, static object)
3. **Set acceleration to 0:** The acceleration from the collision was accounted for above by the velocity calculations in step number 2.

4. Caveats:
  - Step 1 makes the simulation less accurate because you're essentially warping the object back in time (different objects will be warped back different time increments based on object velocity, penetration vector, and collision resolution order). Ideally, you should handle the collision before objects ever intersect!
  - In step 2, the x and y components should be handled separately for more accurate exit velocity angles. Ideally, the exit velocity angle should be based on the normal of the collision.

Please take a look at my [sample asteroids program][2] which demonstrates these concepts.
<hr>

## Next, account for stacked objects:

As you have noted, using velocity to simulate stacked/resting objects does not work well. Velocity is the speed an object is moving, so if it is resting on a static object, velocity should be near 0:

> If I add gravity acceleration to my simulation, the velocity of the
> first dynamic AABB keeps growing even when it is resting on top of the
> second static AABB. Eventually, the velocity will become too big and
> the collision won't be detected (the dynamic AABB will fall through
> the static one).

Most physics simulations need some type of work-around to deal with stacked/touching objects. Otherwise, stacked/touching objects will constantly jitter/bounce because a real-time (gravity) simulation simply cannot be made precise enough. (In the real world, objects really are jittering/bouncing at a microscopic level due to gravity.)

- One method of doing this by is keeping a "grounded" state:
  - Do not apply gravity to objects in a grounded state.
  - If an object collides with an object from below and its velocity is very small it enters the grounded state.
  - An object exits the grounded state when its vertical velocity exceeds a certain positive value.

<hr>

##Update:

- In layman's terms, Newtonian physics says the total energy before and after a collision must match. When two objects crash into each other, their energy is redistributed. Energy is a combination of speed and weight: heavier, faster things have more energy. That's intuitive. However, what's not intuitive is the exact way weights affect the energy redistribution.
- Swapping velocities is a shortcut only for two dynamic, unfixed bodies that have the same mass (static, fixed objects have very large, infinite masses).
- The shortcut when one static body is fixed is: the other dynamic, unfixed body keeps the same speed; only angle is changed (imagine a pool table when a ball hits the rail. The rail essentially has a very large, infinite mass).
- For other cases, like three or more objects, the full Newtonian motion equations must be solved (conservation of momentum and conservation of kinetic energy).
- I'm not sure if the Newtonian equations for motion can be solved for more than two bodies. Fortunately, however, three objects almost never collide at the exact same time. It is sufficient to handle the first two bodies that collide, then handle any following collisions using the new velocities from the previous collision resolutions. This is a good reason to keep your physics time steps as small as possible and handle collisions before any penetrations occur.
- You'll notice in my asteroids demo many bodies are created as bigger rocks are split into smaller ones. However, I always handle collisions between pairs of bodies; never explicitly handling a collision with more than three bodies.

  [1]: http://box2d.org/about/
  [2]: http://www.coolcases.com/asteroids/
  [3]: http://en.wikipedia.org/wiki/Elastic_collision#One-dimensional_Newtonian