Each drop down will have to track the available names based on the selections made previously
Move the $scope.names declaration to the top of your controller
$scope.names = ["Emil", "Tobias", "Linus"];
Then add a names property to your personalDetail objects, this property will be used to track the available names based on previous selections
$scope.personalDetails = [
{
    'names':$scope.names
}];
Now you can modify your addNew function to set the correct number of values when adding a drop down
$scope.addNew = function(){
    $scope.personalDetails.push({ 
        'fname': "", 
        'lname': "",
        'email': "",
        // Make a copy of the values set for the previous drop down
        'names': $scope.personalDetails[$scope.personalDetails.length - 1].names.slice() 
        });
        // Determine the value of the previous selected name
        var previousSelectedName = $scope.personalDetails[$scope.personalDetails.length - 2].fname;
        // Get the index of the previous selected name     
        var index = $scope.personalDetails[$scope.personalDetails.length - 1].names.indexOf(previousSelectedName);
        // Remove the name from the valid names list
        if(index > -1){
            $scope.personalDetails[$scope.personalDetails.length - 1].names.splice(index, 1);
        }
    }
}
Also remember to update the ng-repeat to make use of your new names personalDetail.names property
<tr ng-repeat="personalDetail in personalDetails">                       
    <td>
        <select ng-model="personalDetail.fname" ng-options="x for x in personalDetail.names">
        </select>
    </td>
</tr>
Here is the new JSFiddle demonstarting this
Please note that I did not handle the case where there are no names available to choose from. But this case should be pretty easy to handle.