how does one know which versions of these dependencies one is to use
for the version of the product that they are using?
There are several ways to know which dependency versions you are using. The simplest one is to open up your bundle's jar files and look at the manifest file.
Of course, opening manifests is pretty tedious. You can use your system's Gogo shell to obtain information about the bundles on a running system.
Or you could look for the dependency on git. Use the Liferay tag that corresponds to your system, and subtract 1 from the minor portion of the version you see in the bnd file.
Finally, the logs can help you telling when a dependency is missing or a package version exists with a mismatch in version numbers.
Personally, I would say that the Gogo shell and App manager option is the easiest way.. but sometimes you are on git already..
is this a typical case where one should always be trying to use the
most recent version of dependencies even if the version of the product
is a minor release behind?
No, this is not a good thing for you. Although minors portions of the version scheme usually indicate that things are not likely to break, they do. If you use a method that was added in a minor version, on your running system that method will not be available and debugging can be confusing as you will clearly see that you IDE is even auto completing nonexistent stuff.
Additionally, there is no real advantage on using the latest version to compile your modules as the one running on the system is not updated, the one that will be running is the one that comes with your product (if you have not changed it, installed or embedded it even inside your on module... but if you did adjustments on your bundle, then it is up to you to track...).
You can use version ranges like 3.1.+ to build your modules, assuming that modules compiled with that dependency will work with all dot versions of it in a running system. If the dependency is known to be compatible with the older versions of itself, you can use older versions to build while the system will run a newer one. Liferay does this all the time in their own code (sometimes hidden by the word default). Of course, if you do this you will not be able to enjoy the latest features and IDE provided autocomplete and verification.
You also need to be aware that in OSGi based systems, several versions of the same library is possible. Sometimes, only one runs (singletons) but sometimes several will be available on runtime...so, you can pick the latest of the available...
So, in short: do not use the latest version to build if your system will not be running it. Maybe a range works, but you need to check if that dependency actually cares about being compatible inside that range, according to its versioning scheme.
Useful links: