Here you have something simple for you to experiment, there are many ways of doing it.
# How many Jobs?
$testJobs = 5
[System.Collections.ArrayList] $jobs = 1..$testJobs | ForEach-Object {
    Start-Job {
        'Hello from Job {0}' -f [runspace]::DefaultRunspace.InstanceId
        # Set a Random timer between 5 and 10 seconds
        Start-Sleep ([random]::new().Next(5, 10))
    }
}
$total = $running = $jobs.Count
$completed = 0
$results = while($jobs) {
    $id = [System.Threading.WaitHandle]::WaitAny($jobs.Finished, 200)
    if($id -ne [System.Threading.WaitHandle]::WaitTimeout) {
        $jobs[$id] | Receive-Job -Wait -AutoRemoveJob
        $jobs.RemoveAt($id)
        $running = $total - ++$completed
    }
    Clear-Host
    @(
        'Total Jobs'.PadRight(15) + ': ' + $total
        'Jobs Running'.PadRight(15) + ': ' + $running
        'Jobs Completed'.PadRight(15) + ': ' + $completed
    ) | Write-Host
}
$results | Format-Table
You could also use Write-Progress:
$total = $running = $jobs.Count
$completed = 0
$results = while($jobs) {
    $id = [System.Threading.WaitHandle]::WaitAny($jobs.Finished, 200)
    if($id -ne [System.Threading.WaitHandle]::WaitTimeout) {
        $jobs[$id] | Receive-Job -Wait -AutoRemoveJob
        $jobs.RemoveAt($id)
        $running = $total - ++$completed
    }
    $progress = @{
        Activity = 'Waiting for Jobs'
        Status   = 'Remaining Jobs {0} of {1}' -f $running, $total
        PercentComplete = $completed / $total * 100
    }
    Write-Progress @progress
}
$results | Format-Table
This answer shows a similar, more developed alternative, using a function to wait for Jobs with progress and a optional TimeOut parameter.