Create separate files for header and footer(as they are common for all the pages and it does not make sense to make them a part of a single page)
Keep common elements(Like Search/Back/Next etc) in separate file(The idea is to remove any kind of duplication and keeping the segregation logical)
For Driver, its a good idea to create a separate Driver class and keep Driver as static so that it can be accessed across all pages! (I have all my webpages extend DriverClass)
The functions used in PageObjects are broken down into smallest possible chunk keeping in mind the frequency and the way in which they will be called(The way you have done for login- although login can be broken down into enterUsername and enterPassword functions but still keeping it as Login function is more logical because in majority of the cases, the Login function would be called rather than separate calls to enterUsername and enterPassword functions)
Using PageObjects itself segregates Test script from the elementLocators
Have utility functions in separate utils folder(like DateUtil, excelUtils etc)
Have configurations in separate conf folder(like setting the environment on which the tests need to be run, configuring the output and input folders)
Incorporate screenCapture on failure
Have a static wait variable in the DriverClass with some implicit wait time as you have done
Always try to have conditional waits rather than static waits like: wait.until(ExpectedConditions). This ensures that the wait is not slowing down the execution unnecessarily.