Here's a starting point (this applies for Eclipse 3.4 and later, when the P2 repository was introduced, earlier versions store their configuration differently. IIRC you could see all the plugins and features in platform.xml).
Create a new plugin project (New->Other->Plug-in Development->Plug-in Project) with the "Hello World" template then drop this code into the run method of the SampleAction.
Run the plugin as a test Eclipse Application and select Sample Menu->Sample Action, the plugins that don't belong to a feature will be output to the parent workspace's console. When I ran this there were quite a few more than I expected, I've had a few looks through and can't spot the logic error.
Edit, found logic error, was using the wrong array index used in innermost loop. Still not quite right though.
Edit 2. (Facepalm moment) Found the problem. Be sure to run the target workspace with all workspace and enabled target plugins enabled, or it will skew your results, obviously. If you install the plugin and dress it up a little bit you won't have this problem.
//get all the plugins that belong to features
IBundleGroupProvider[] providers = Platform.getBundleGroupProviders();
Map<Long, IBundleGroup> bundlesMap = new HashMap<Long, IBundleGroup>();
if (providers != null) {
for (int i = 0; i < providers.length; i++) {
IBundleGroup[] bundleGroups = providers[i].getBundleGroups();
System.out.println("Bundle groups:");
for (int j = 0; j < bundleGroups.length; j++) {
Bundle[] bundles = bundleGroups[j] == null ? new Bundle[0] : bundleGroups[j]
.getBundles();
System.out.println(bundleGroups[j].getIdentifier());
for (int k = 0; k < bundles.length; k++) {
bundlesMap.put(bundles[k].getBundleId(), bundleGroups[j]);
}
}
}
}
BundleContext bundleContext = Activator.getDefault().getBundle().getBundleContext();
if(bundleContext instanceof BundleContextImpl) {
Bundle[] bundles = ((BundleContextImpl)bundleContext).getBundles();
System.out.println("Orphan Bundles:");
for (int i = 0; i < bundles.length; i++) {
if(!bundlesMap.containsKey(bundles[i].getBundleId())) {
System.out.println(bundles[i].getSymbolicName());
}
}
}