The gist of it is: in addition to setting the velocity of the objects, you also want to move them so the next tick they are not intercepting. You can now stop reading this answer.
Why is that the solution?
What happens is that the objects collided at some time between the last tick to the current one. That is, the instant of collision is a fraction of your delta time. So to simulate the full span of the delta time, you can imagine that the objects were moving, collided, and then began moving according to their bounce. So at the end of the delta time the position is also wrong and you should correct it.
Now, you need to make a trade-off between precision and performance. Using realistic logic to figure out where the object ends up will have an impact in performance that ultimately will mean you won't be able to handle as many objects.
Thankfully, we are making games, and games don't need to be realistic. So go ahead and simply move the objects so they are no longer intercepting.
The cheap approach is to figure out the distance between the object, and at what distance they should be to not intercept, and move them accordingly. However, this approach is infamous for causing troubles by pushing objects out the wrong direction.
An slightly less cheap approach - but also one that causes less troubles - considers their velocity, and moves them in the opposite direction they came from.
Other related problems
Too many bounces
Another issue related to delta time is too many bounces in the same tick. The issue is that when you push the object out so it is no longer intercepting, they end up intercepting something else. And then you solve that other collision, and it results in yet another collision and so on.
Have a hard cap on how many you will solve per object. It is better that at some point the physics engine gives up and leaves some objects intercepting than to kill the performance of the game.
Yet another issue related to delta time is tunneling. It happens when your objects are too fast (or you ticks are too long), so that they can leap from one side to the other without registering collisions.
The cheap approach for these is to enforce a maximum/terminal velocity. So that objects don't get to move so fast that they can tunnel through each other (having a maximum velocity will also help with the prior issue).
And, of course, you can increase the tick frequency.
About the expensive approaches
You want to find out what is the instant when the objects would have collided. Which you can do since you have the motion equation for them. To make it easier, consider the frame of reference of one of the objects and work there. In the frame of reference of an object, itself is static, and the other object is making the combined motion of both of them… And you want to find out when the distance between their surfaces is zero. Setup the equation and solve for time (which is trivial if they just have position and velocity. No so much if they have acceleration, friction, drag, dampening, etc…).
Once you have the instant they collided, you can compute where they would have been at that time, and place them there. Then compute the speed after the bounce. And if you are so inclined, compute how much they move for the remainder of the delta time. And that could lead to another collision…
And about tunneling, you could collide the shape the objects sweep during their motion (e.g instead of colliding circles, you collide a capsule that goes from the prior position of the circle to the current one). You would have to change your approach to discard possible collision early, because, as you can imagine, you cannot simply check for collision with objects in the same area where the object ended… You need to consider their velocity, and check for collision with objects in the areas along the motion. Search for continuous collision detection and continuous physics simulations for more details.