Similar to this answer, we can use a driver function to capture the relevant details - but instead of using the values to calculate the velocity and/or acceleration, we can simply store the previous data value into a queue and retrieve the value after the specified number of frames.
Here's the code you'll need - paste it into a Text Editor window named something like 'delay.py'. Tick the 'Register' checkbox to ensure it's run automatically whenever the .blend is loaded - or just run it manually using the 'Run Script' button.
import bpy
attributes = {}
def drv_delay(frame, attr, delay, value):
# Used to delay the value by a specified number of frames.
# Determine whether we already have a value for this attribute
if attr in attributes:
attribute = attributes[attr]
else:
# Not found - create a new record for it and store it
attribute = {'frame':frame, 'dataqueue': []}
attributes[attr] = attribute
if frame <= 1:
del(attribute['dataqueue'][:])
# Only store the value on change of frame (to guard against being called multiple times per frame)
if frame != attribute['frame']:
# Store this value in the queue
attribute['dataqueue'].append(value)
# Discard any elements that are more than the delay period
while len(attribute['dataqueue']) > (delay+1):
del(attribute['dataqueue'][0]) #remove one from head of the list
# Store frame
attributes[attr]['frame'] = frame
#return the value at the head of the list
if len(attribute['dataqueue']) == 0:
return value
else:
return attribute['dataqueue'][0]
if 'drv_delay' in bpy.app.driver_namespace:
del bpy.app.driver_namespace['drv_delay']
bpy.app.driver_namespace['drv_delay'] = drv_delay
The script defines a driver function and registers it in the driver namespace to make it available to use in driver scripted expressions. This means that we can use a new function in the driver expression as follows :
drv_delay(<frame>, <attribute>, <delay>, <value>)
Where frame is the current frame (so we can detect frame change for handling the delay), attribute is a name for this 'delay queue' - each property will need to be given a unique name so that blender knows which one we are referring to), delay is how many frames the 'queue' should buffer, value is the actual value that we want to delay.
To use it, set up the driver Scripted Expression as something like :
drv_delay(frame,"cube_y",10, var)
This sets up a delay queue named 'cube_y' (for the y-coordinate of the cube) with a delay of 10 frames. var is the value being delayed. The function will essentially return the var value passed in 10 frames ago.
To demonstrate, here's an example with an Empty moving in the scene, with a Cube delayed by 10 frames and a Sphere delayed by 15 frames. The queues are automatically reset at frame 1 so the motion can restart afresh.

Blend file included 
I will have a play with this to see what needs to happen and toy around with your blend file.
– ToxsickcitY May 16 '18 at 06:36