Here's my attempt at a completely generic solution, in Python:
First, a generic "wait" function (use a WebDriverWait if you like, I find them ugly):
def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
Next, the solution relies on the fact that selenium records an (internal) id-number for all elements on a page, including the top-level <html> element.  When a page refreshes or loads, it gets a new html element with a new ID.
So, assuming you want to click on a link with text "my link" for example:
old_page = browser.find_element_by_tag_name('html')
browser.find_element_by_link_text('my link').click()
def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id
wait_for(page_has_loaded)
For more Pythonic, reusable, generic helper, you can make a context manager:
from contextlib import contextmanager
@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')
    yield
    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id
    wait_for(page_has_loaded)
And then you can use it on pretty much any selenium interaction:
with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()
I reckon that's bulletproof!  What do you think?
More info in a blog post about it here.