Code compiled against 3.0 or 3.5 may run on the 2.0 framework, but only if you do not use any libraries that are specific to the 3.0+ framework. One good way to find what's causing your code to fail is to switch your target to 2.0 and change things so that it compiles. Since one of your target installations is .NET 2.0, you are going to have to write .NET 2.0 code; this is not unique to .NET. In the past, writing an application that executed in both Win95 and WinNT involved extra work for the developer to carefully make sure the appropriate API was used.
Technically, 3.5-targetted code can run on 2.0 with no problems, but there's some gotchas you have to watch for. If anything accesses something that is unavailable in .NET 2.0, that will fail. This doesn't happen when the application starts, it happens when the application tries to make the call. I tested this by making a console application that does a little bit of output, then tries to display a WPF window. The output is made, but the application throws an exception when it tries to display the window on a machine with nothing but .NET 2.0.
Another gotcha is that VS 2008 actually comes with the .NET Framework 2.0 SP1, and there are a few types and methods in SP1 that are not in the normal 2.0 Framework. Visual Studio will not flag these methods as unsafe.
Finally, if this is a web application, the default web.config file for 3.5-targeted projects is very different than the web.config file for 2.0-targeted projects. Make sure you're distributing a compatible web.config. This is likely the problem you are encountering. A cheap workaround might be to change your target to .NET 2.0, copy that web.config, and use it in this case. Keep in mind that if you are using any 3.0+-specific language features or types your code will still fail, but this should get you past the web.config.