There are a couple of ways to do this in MVVM. I would agree with Steve Robbins that "it's not your VM's responsibility to know how to load another screen", but it is your VM's responsibility to receive notification from the view that something has occured that requires display of a new screen, and to pass that notification along to the object that will do the loading and unloading of views as they are needed. The point to remember is that each VM is bound to a view, and the VM gets replaced when a new view is displayed. So, something else, in the nature of an executive, needs to do the replacing.
That's why Composite WPF (Prism) framework is getting so much attention. I struggled with the same issues that you have raised before learning Prism, which provides the executive. I assume your Category list is being displayed in an items control. Basically, in your situation, I would probably bind the SelectedItem property of the control to a SelectedItem property in the VM. I would have the setter of that property invoke an MVVM method that notifies the Prism framework of the selection, and that passes along the SelectedItem that was passed to the property setter. I would use Prism to load the module with the page that needs to be displayed.
The nice thing about Prism is that it will work if you want your Product page to replace your Category page, and it will work just as well if you want to show a Product pane next to a Category pane in the same window. It's a simple matter of specifying one region or two when you set up your Shell (the main window).
There is a learning curve to Prism, but it isn't very steep. It works very well with MVVM, and it is a great framework for any application that can benefit from partitioning. I consider it to be a key element of WPF application design.