I suppose Crystal installs to GAC.
So you need to programmatically browse Global assembly cache and look for Crystal assembly there
GAC can be programmatically managed thru Windows API.
Here you will find a simple wrapper that allows to manage GAC from a managed code
But I would not recommend you to go this way. :)
The good solution is usually too check for all required assemblies during the installation of your software, I suppose Windows Installer has functions to check for assemblies
However, it is not always OK.
Suppose if you would like users to run your program even without Crystal, but do not allow show reports if Crystal is not installed.
In this case you should decouple all Reports functionality from other forms. You should create a separate project with Crystal Reports functionality, let's call it MyReports. Only that project should reference to Crystal assemblies, while other should not. Other projects also should not directly reference to MyReports.
And finally you should use reflection to call a report viewer that is implemented inside MyReports from other projects.
Usually you will write try / catch around the procedure where you will use reflection to load MyReports assembly from file. So, if Crystal or something else not exist, it will throw exception, you will display it to user, but the other parts of the program will work.
Also, you can read about Dependency Injection design pattern, it helps to manage such problems.