Adding to Alexander Pavlov's answer, I found that a little extra work is required to copy the project properties (such as referenced projects) in addition to just copying the project files.
public static IProject copyProject(String projectName) throws CoreException {
IProgressMonitor m = new NullProgressMonitor();
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IProject project = workspaceRoot.getProject(projectName);
IProjectDescription projectDescription = project.getDescription();
String cloneName = projectName + "_copy";
// create clone project in workspace
IProjectDescription cloneDescription = workspaceRoot.getWorkspace().newProjectDescription(cloneName);
// copy project files
project.copy(cloneDescription, true, m);
IProject clone = workspaceRoot.getProject(cloneName);
// copy the project properties
cloneDescription.setNatureIds(projectDescription.getNatureIds());
cloneDescription.setReferencedProjects(projectDescription.getReferencedProjects());
cloneDescription.setDynamicReferences(projectDescription.getDynamicReferences());
cloneDescription.setBuildSpec(projectDescription.getBuildSpec());
cloneDescription.setReferencedProjects(projectDescription.getReferencedProjects());
clone.setDescription(cloneDescription, null);
return clone;
}