if you check the Winter16 release notes on Process Builder regarding Schedule Multiple Groups of Actions, I'm fairly confident you should be able to do this without a trigger. But, as I've not tried it, I can't say for certain. I'll add that this would seem to be more of a management issue with holding employees accountable for their work.
Knowing that overdue tasks show up on someone's desktop every time they log-in would cause me to be concerned if there's such a big issue with Tasks that these employees need 2nd and 3rd reminders to get them completed, especially when their managers aren't being cc'd on these emails. But hey, if this is what your management wants you to do, I 'get' that it's your assignment to satisfy.
I've modified the main for loop in the center of your trigger to show you how this needs to be done. You can add any additional fields you wish following the same format. Before I forget, in order for the carriage returns you've included to work, I believe you need to specify a long text area field for the string variable that holds them.
Map<Id, User> userMap = new Map<Id, user>([select id, Name, email FROM USER where id in: ownerIdTaskIdMap.keySet()]); //NOTE: Added `Name` to this query from higher up in your code sting subj = 'overdue task'; // additional string variable string emlb; // additional string variable //loop for(Id ownerId : ownerIdtaskIdMap.keySet()){ //userEmail = userMap.get(ownerId).Email; // not needed, can get directly from map within this loop taskIdList = ownerIdtaskIdMap.get(ownerId); if(taskIdList.size() > 0){ // test to see if a user has more than one task that's overdue for(task tsk : taskIdList){ // compose your email body content emlb = 'Hi '+ userMap.get(OwnerId).Name + ',\n\n You have open tasks that are overdue.\n\n Please update Task:' + tsk.Id +'/n/n Subject: '+ tsk.Subject +'./n/n Type: ' + tsk.Type +'./n/n Due Date: '+ tsk.ActivityDate +'./n/n/n'; } // end for(task tsk : taskIdList) emailBody = emlb + '/n/n Thank you'; // adds 'Thank you' to the list of tasks from the loop above }else if(taskIdList.size() = 0){ emailBody = 'Hi '+ userMap.get(OwnerId).Name + ',\n\n You have an open task that is overdue.\n\n Please update '+ taskIdList.Id +'./n/n Subject: ' + taskIdList.Subject +'./n/n Type: ' + taskIdList.Type +'./n/n Due Date: '+ taskIdList.ActivityDate +'./n/n/n Thank you'; } // end if statements } //end for(Id ownerId : ownerIdtaskIdMap //initiallize messaging method Messaging.SingleEmailMessage singleMail = new Messaging.SingleEmailMessage(); singleMail.setToAddresses(new String[] {userMap.get(OwnerId).Email}); singleMail.setSubject(subj); singleMail.setPlainTextBody(emailBody); emails.add(singleMail); //add mail }